// Deferred Shading Compositor
// (c) jimon game studio

#ifndef JEH_CDEFERREDSHADINGCOMPOSITOR
#define JEH_CDEFERREDSHADINGCOMPOSITOR

#include "ICompositor.h"
#include "jeMaterialResource.h"
#include "ICameraSceneNode.h"

namespace je
{
	namespace scene
	{
		//! Deferred Shading Compositor
		class CDeferredShadingCompositor:public je::scene::ICompositor
		{
		protected:
			u1 EnableAA;

			u32 MaxLightsPerPass;
		
			video::IRenderTargetTexture * FBO_AA;
			video::IRenderTargetTexture * FBO_Downsample;
			video::IRenderTargetTexture * FBO_GBuffer;

			video::jeMaterial * DeferredShadingMaterial;

			video::IShaderVariable * CameraNear;
			video::IShaderVariable * CameraFar;
			video::IShaderVariable * CameraFov;
			video::IShaderVariable * CameraAspectRatio;
			video::IShaderVariable * LightsPosition;
			video::IShaderVariable * LightsCount;

			ICameraSceneNode * ScreenQuadCamera;

			jeVector2di ScreenSize;

			video::IShaderGlobalVariable * Transparent_LightPosition;
			video::IShaderGlobalVariable * Transparent_LightPosition_Count;

			class CTransparentLightPositionSetupCallback:public je::video::IPreRenderOperationCallback
			{
			public:
				typedef jeDynamicArray<jeVector3df> LightPositionsArrayType;
			protected:
				video::IShaderVariable * CurrentTransparentLightPosition;
				video::IShaderVariable * CurrentTransparentLightPositionCount;
				LightPositionsArrayType * CurrentLightPositions;
			public:
				CTransparentLightPositionSetupCallback(video::IShaderVariable * Transparent_LightPosition,video::IShaderVariable * Transparent_LightPositionCount)
					:CurrentTransparentLightPosition(Transparent_LightPosition),CurrentTransparentLightPositionCount(Transparent_LightPositionCount)
				{
				}
				~CTransparentLightPositionSetupCallback()
				{
				}
				void OnRenderOperation(video::RenderOperationType Type,video::jeRenderOperation * Data)
				{
					CurrentTransparentLightPosition->SetVector(CurrentLightPositions->GetPtr(),CurrentLightPositions->GetSize());
					CurrentTransparentLightPositionCount->Sets32(CurrentLightPositions->GetSize());
					IPreRenderOperationCallback::OnRenderOperation(Type,Data);
				}
				void SetLightPositions(LightPositionsArrayType * LightPositions)
				{
					CurrentLightPositions = LightPositions;
				}
			};

			//! Setup callback
			CTransparentLightPositionSetupCallback * CurrentCallback;

			//! Create Deferred Shading Textures
			s32 CDeferredShadingCompositor::CreateDSTextures(const jeVector2di & Size);
		public:
			//! Constructor
			CDeferredShadingCompositor(ISceneManager * SceneManager);

			//! Destructor
			~CDeferredShadingCompositor();

			//! On Render
			void OnRender();

			//! Serialize
			void Serialize(core::ISerializeStream * SerializeStream);

			//! Get Compositor Type Name
			jeStringc GetCompositorTypeName()
			{
				return "DeferredShadingCompositor";
			}
		};
	}
}

#endif
